Skip to content

Schema clean-up: chemdcat-ap inheritance, quality audit, catalyst/reaction classification, real-world example datasets - #120

Merged
HendrikBorgelt merged 7 commits into
nfdi4cat:mainfrom
HendrikBorgelt:clean-up-the-schema
Jul 14, 2026
Merged

Schema clean-up: chemdcat-ap inheritance, quality audit, catalyst/reaction classification, real-world example datasets#120
HendrikBorgelt merged 7 commits into
nfdi4cat:mainfrom
HendrikBorgelt:clean-up-the-schema

Conversation

@HendrikBorgelt

@HendrikBorgelt HendrikBorgelt commented Jul 14, 2026

Copy link
Copy Markdown
Member

closes #109
closes #59
closes #34
closes #111
closes #53
closes #110
closes #112

Summary

Schema clean-up and quality pass across CoreMeta4Cat: proper LinkML inheritance from chemdcat-ap (CatalyticReaction is_a: ChemicalReaction, ChemicalReactor is_a: Reactor), a full modelling/mapping audit (mismatched ontology mappings, is_a relation-typing sweep across 295 slots, multivalued anti-patterns), catalysis-specific reactor slots, three fully worked real-world example datasets validated as test data, and expanded documentation (inheritance, catalysis-dataset model, working-with-data guide, contributing/getting-started fixes).

This also touches the same area as PR #118 (catalyst/reaction classification) — see "On the catalyst_type / has_catalyst_type conflict" below before reviewing the reaction_ap changes.

On the catalyst_type / has_catalyst_type conflict

This branch and the already-merged #118 independently redesigned catalyst/reaction classification while diverging from the same base. This PR keeps this branch's design — catalyst_type (CatalysisResearchFieldEnum) + catalyst_form (CatalystFormEnum) as two slots, and rdf_type (DCAT-AP-PLUS Pattern 3) for reaction type — instead of #118's has_catalyst_type: CatalystType / has_reaction_type: ReactionType class hierarchies. Reasoning:

  • CatalystType conflates two independent axes. Its subclasses HeterogeneousCatalyst/HomogeneousCatalyst/BioCatalyst/ElectroCatalyst/PhotoCatalyst (catalytic regime) sit as siblings of ThinFilmCatalyst/BulkCatalyst/PowerderedCatalyst/DepositedSampleCatalyst/SupportedCatalsyt (physical form) in one flat hierarchy. These aren't mutually exclusive — a catalyst is routinely both "heterogeneous" and "supported" at once. The five form-related subclasses use VOC4CAT ids identical to this branch's CatalystFormEnum permissible values (0000019/0007015/0000017/0000038/0007034), confirming both sides are describing the same underlying vocabulary, just merged into one axis on Added new classes & slots in coremeta4cat_reaction_ap.yaml #118's side. The practical effect shows up in Added new classes & slots in coremeta4cat_reaction_ap.yaml #118's own test data: has_catalyst_type: [{value: "heterogeneous, supported metal oxide"}] — free text stuffed into a generic value field, which defeats the purpose of having ten typed subclasses.
  • has_reaction_type duplicates an existing mechanism. CatalyticReaction.rdf_type already carries reaction-type classification via Pattern 3 (the same convention used by Synthesis, Characterization, Simulation, and CatalysisDataset throughout this schema) and is already recommended. Added new classes & slots in coremeta4cat_reaction_ap.yaml #118's ReactionType class_uri (VOC4CAT:0007010) is the same URI already documented as the example value for rdf_type here — same concept, two competing mechanisms for asserting it.

Not claiming #118 was wrong to attempt — it was explicitly a stopgap while this work was in progress. Happy to walk through the reactor-slot and ReactorPerformanceMeasures/Conversion/SpaceTimeYield/Selectivity additions from #118 separately; those don't conflict with this design and may be worth keeping.

On #116 / #117 (cardinality of catalyst_type / reaction type)

Deliberately left catalyst_type and reaction rdf_type as recommended rather than required, per #117's request. In research contexts, classification can be genuinely disputed (a researcher may argue a catalyst is type A, not type B) or the catalyst may not fit any current CatalysisResearchFieldEnum value yet — forcing a mandatory value would push contributors into a premature or contested classification rather than leaving the field open until vocabulary/consensus catches up. Rationale is also recorded as schema comments next to both slots in coremeta4cat_reaction_ap.yaml. Open to discussion in a follow-up issue if a different tradeoff is preferred — flagging #116 as the place to continue that.

Other issues addressed in this PR

Already resolved by earlier work on this branch, no action taken: #112's original ask (contributing.md inbox description) was already covered before this PR; #53's Excel-tab-naming complaint no longer applies (sheets are Synthesis/Characterization/Reaction/Simulation/CoreMeta4Cat now, not the old split names). #42 will be answered directly on the issue (not a schema change). #69 (broken download link) and #115 (docs home-page PR) are unrelated to this branch's scope.

Test plan

  • just test (schema generation, pytest, linkml-run-examples against tests/data) — all green
  • 3 real-world example CatalysisDataset records validate end-to-end
  • just gen-doc regenerated cleanly, no orphaned references
  • Reviewer sanity-check on the catalyst_type/reaction_type reasoning above

…esolve it

CatalyticReaction now specializes chemdcat-ap's ChemicalReaction instead of
re-declaring EvaluatedActivity in parallel, and ChemicalReactor specializes
Reactor instead of Device -- both previously asserted the same class_uri as
their chemdcat-ap counterpart without an is_a relationship.

The custom Excel/docs tooling (schema_to_excel.py, inbox_to_schema.py,
generate_schema_docs.py) hand-rolls its own schema merge and previously only
understood mixins, not is_a, so it was blind to inherited chemdcat-ap slots.
Teaches it to climb is_a chains for slot resolution, mark inherited rows as
read-only reference material in the Excel workbook, and skip non-owned slots
in the inbox workflow's editability and deletion-detection checks so
inherited fields don't trigger false "will be removed" warnings.
Fixes cross-contaminated ontology mappings (Catalyst/ChemicalProduct
exact_mappings pointing at each other's terms, an overly-specific Duration
class_uri, a wrong lense_mode slot_uri, HeatingRate's class_uri), sweeps 295
slots for correct is_a relation-typing, fixes multivalued anti-patterns on
booleans/counts/min-max pairs, and resolves the reactant/used_reactant
overlap left over from the chemdcat-ap inheritance change. Also fixes a
self-referential recursion bug in the sunburst chart generator and adds the
new precipitating_concentration/precursor_quantity CURIE fixes.

Test fixtures updated to match the corrected slot names/ranges.
…tion

Adds operating-condition slots for each of the 8 ChemicalReactor subclasses
(ElectrochemicalReactor, CSTR, PlugFlowReactor, Autoclave, SlurryReactor,
Microreactor, FixedBedReactor, FluidizedBedReactor), and introduces
catalyst_type (CatalysisResearchFieldEnum) + catalyst_form (CatalystFormEnum)
as two independent slots on CatalyticReaction, replacing an earlier single
overloaded field. Reaction type classification stays on rdf_type via the
existing DCAT-AP-PLUS Pattern 3 convention (already used by Synthesis,
Characterization, Simulation, and CatalysisDataset), rather than adding a
dedicated slot.

catalyst_type/catalyst_form and reaction rdf_type are both kept
`recommended` rather than `required`: catalyst/reaction classification can
be genuinely disputed or not yet covered by the controlled vocabulary for a
novel case, and a mandatory field would force a premature or contested
classification. See the rationale recorded directly on these slots below
for the fuller argument, including why this two-slot design is kept instead
of a CatalystType/ReactionType class hierarchy also explored elsewhere.
Adds a dedicated catalysis-dataset.md page documenting the CatalysisDataset
model and its rdf_type classification pattern. Rewrites the stale
design-patterns.md content and adds a section on the new chemdcat-ap
inheritance chain. Fixes the contributing.md gap around the Excel-inbox
edit-and-PR workflow (previously undocumented, pushing contributors to
GitHub issues only) and aligns inbox/README.md with it.
Adds 3 fully-worked CatalysisDataset records built from real experimental
data (mixed CO/CO2 methanation, citral hydrogenation, carbonylation
chemistry), validated end-to-end against the schema and published as
docs/assets/examples for reference. Adds generate_example_outputs.py to
publish them during doc generation, and updates the CI workflow to run
`just test` (schema + pytest + linkml-run-examples) and upload the example
validation output as a build artifact.
Fixes CURIEs for precursor_quantity and adds the new
precipitating_concentration slot (nfdi4cat#109, nfdi4cat#59, nfdi4cat#34).
Renames "CatCore" to "CoreMeta4Cat" and aligns the vocabulary workbook's
sheet-description table with its actual current sheets (nfdi4cat#111, nfdi4cat#53).
Generalizes "Voc4Cat term" wording to "CURIE" since the schema also uses
CHMO/QUDT/OBI/SIO/NCIT/AFE terms (nfdi4cat#110). Documents the Excel workbook's
structure/colour-coding/columns and the inbox PR workflow in detail, with
real workbook screenshots and the automated check's actual validation
messages (nfdi4cat#112).

Regenerates all derived artifacts (Python dataclasses/pydantic models,
generated schema docs, Excel workbook, sunburst charts) from the final
schema state.
…rtifacts

Rebasing onto upstream/main surfaced additional duplication beyond the
already-resolved coremeta4cat_reaction_ap.yaml conflict: PR nfdi4cat#118 also added
has_cathode/has_anode/has_cell_operating_mode/has_active_area/
has_faradaic_current and several catalyst-bed/stirrer geometry slots to
coremeta4cat_common.yaml that duplicate slots already defined locally in
coremeta4cat_reaction_ap.yaml (same concepts, same VOC4CAT terms in most
cases, different slot names), plus has_conversion/has_space_time_yield/
has_selectivity referencing nfdi4cat#118's Conversion/SpaceTimeYield/Selectivity
classes -- which aren't included in this PR (see the PR description's note
on keeping those for separate discussion). Removes the now-orphaned
duplicates so the schema resolves cleanly, and regenerates all derived
artifacts against the final merged state.
@HendrikBorgelt
HendrikBorgelt merged commit bcd9e34 into nfdi4cat:main Jul 14, 2026
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant